﻿using Microsoft.EntityFrameworkCore;
using star_questionnair.DTOs;
using star_questionnair.Models;
using star_questionnair.Utilities;
using star_questionnair.Models.Enum;
namespace star_questionnair.Services.impl;

public class ResponseService : IResponseService
{
    private readonly ApplicationDbContext _dbContext;

    private readonly IAnswerService _answerService;

    public ResponseService(ApplicationDbContext dbContext,IAnswerService answerService)
    {
        _dbContext = dbContext;
        _answerService = answerService;
    }
    
    public Response SubmitWholeResponse(Response response)
    {
        // using var transaction = _dbContext.Database.BeginTransaction(); // 开启事务
        try
        {
            var answers = new List<Answer>();

            DateTime? oldTime = response.SubmittedTime;
            
            response.SubmittedTime = DateTime.Now;
            response.UpdatedTime = DateTime.Now;

            // 判断是否已存在 Response
            if (GetCountOfResponse(response) > 0)
            {
                // 获取已存在的 Response ID
                var existingResponse = SelectBy2Id(response.UserId, response.QuestionnaireId);
                // 分离已有的实体
                _dbContext.Entry(existingResponse).State = EntityState.Detached;
                
                // 直接修改已加载的实体
                existingResponse.SubmittedTime = response.SubmittedTime;
                existingResponse.UpdatedTime = response.UpdatedTime;
                
                // 设置新的 Response ID
                response.Id = existingResponse.Id;

                // 根据 Response ID 获取现有的 Answer 并删除
                var existingAnswers = GetListAnswerByResponseId(response.Id);
                foreach (var answer in existingAnswers)
                {
                    _answerService.DeleteAnswerById(answer.Id);
                }

                // 更新 Response
                _dbContext.Responses.Update(response);

                // 保存新的答案
                foreach (var a in response.Answers)
                {
                    a.ResponseId = response.Id;

                    var question = _dbContext.Questions.FirstOrDefault(q => q.Id == a.QuestionId);
                    if (!string.IsNullOrWhiteSpace(a.Text))
                    {
                        if (question.Type.Equals(QuestionEnum.LevelQuestion.GetType().Name, StringComparison.OrdinalIgnoreCase))
                        {
                            a.Level = int.Parse(a.Text); // 程度题
                        }
                        else if (question.Type.Equals(QuestionEnum.SortQuestion.GetType().Name, StringComparison.OrdinalIgnoreCase))
                        {
                            a.Sort = int.Parse(a.Text); // 排序题
                        }

                        _dbContext.Answers.Add(a);
                        answers.Add(a);
                    }
                }

                _dbContext.SaveChanges(); // 保存更改到数据库
                // transaction.Commit();    // 提交事务

                response.Answers = answers;
                return response;
            }
            else
            {
                response.Id = 0; // Response 不存在
                return response;
            }
        }
        catch (Exception)
        {
            // transaction.Rollback(); // 回滚事务
            throw;
        }
    }
    
    private void UpdateById(Response response)
    {
        var existingResponse = _dbContext.Responses.Find(response.Id);
        if (existingResponse != null)
        {
            existingResponse.StartTime = response.StartTime;
            _dbContext.SaveChanges();
        }
    }
    public Response Start(Response response)
    {
        // 设置开始时间
        response.StartTime = DateTime.Now;

        // 检查是否已存在该用户的 Response
        if (GetCountOfResponse(response) > 0)
        {
            // 如果存在，更新现有的 Response
            var existingResponse = SelectBy2Id(response.UserId, response.QuestionnaireId);
            response.Id = existingResponse.Id;
            UpdateById(response); // 更新数据库中的记录
            return response;
        }

        // 如果不存在，插入新的 Response
        _dbContext.Responses.Add(response);
        _dbContext.SaveChanges();

        // 查询新插入的 Response
        var insertedResponse = _dbContext.Responses
            .FirstOrDefault(r => r.QuestionnaireId == response.QuestionnaireId && r.UserId == response.UserId);

        return insertedResponse ?? response; // 返回插入后的结果
    }

    public void UpdateResponse(Response response)
    {
        response.UpdatedTime = DateTime.Now;

        var existingResponse = _dbContext.Responses.FirstOrDefault(r => r.Id == response.Id);
        if (existingResponse == null)
        {
            throw new Exception("Response not found");
        }

        // 更新字段
        existingResponse.UpdatedTime = response.UpdatedTime;
        existingResponse.StartTime = response.StartTime;
        existingResponse.QuestionnaireId = response.QuestionnaireId;
        existingResponse.UserId = response.UserId;
        existingResponse.SubmittedTime = response.SubmittedTime;

        _dbContext.SaveChanges();
    }

    public Response UpdateWholeResponse(Response response)
    {
        // 更新提交时间和更新时间
        response.SubmittedTime = DateTime.Now;
        response.UpdatedTime = DateTime.Now;

        // 根据 response ID 获取现有的答案并删除
        var existingAnswers = GetListAnswerByResponseId(response.Id);
        foreach (var answer in existingAnswers)
        {
            _dbContext.Answers.Remove(answer); // 删除现有答案
        }

        // 插入新的答案
        var newAnswers = new List<Answer>();
        foreach (var a in response.Answers)
        {
            a.ResponseId = response.Id;
        
            // 根据 QuestionId 获取问题类型
            var question = _dbContext.Questions.FirstOrDefault(q => q.Id == a.QuestionId);
            if (question == null)
            {
                throw new Exception($"Question with ID {a.QuestionId} not found");
            }

            // 根据问题类型更新答案属性
            if (QuestionEnumExtensions.IsLevelType(question.Type))
            {
                a.Level = int.Parse(a.Text);
            }
            else if (QuestionEnumExtensions.IsSortType(question.Type))
            {
                a.Sort = int.Parse(a.Text);
            }

            _dbContext.Answers.Add(a);
            newAnswers.Add(a);
        }

        // 更新 response 并保存
        response.Answers = newAnswers;
        _dbContext.Responses.Update(response);
        _dbContext.SaveChanges();

        return response;
    }

    public int GetResponseCountByQuestionId(int questionId)
    {
        // 获取对应的问卷
        var questionnaire = GetQuestionnaireByQuestionId(questionId);
        if (questionnaire == null)
        {
            throw new Exception($"Questionnaire for Question ID {questionId} not found.");
        }

        // 获取与问卷关联的响应列表
        var responses = GetListResponseByQuestionnaireId(questionnaire.Id);

        // 返回响应数量
        return responses.Count;
    }

    public async Task<List<Response>> GetAllResponsesByQuestionnaireIdAsync(int questionnaireId)
    {
        // 获取与指定 questionnaireId 相关的所有 Response，并按 ResponseId 排序
        var responses = await _dbContext.Responses
            .Where(r => r.QuestionnaireId == questionnaireId)
            .OrderBy(r => r.Id) // 或者根据具体需求排序
            .ToListAsync();

        return responses;
    }

    public Questionnaire GetQuestionnaireByQuestionId(int questionId)
    {
        // 查找对应的 Question
        var question = _dbContext.Questions.FirstOrDefault(q => q.Id == questionId);
        if (question == null)
        {
            throw new Exception($"Question with ID {questionId} not found.");
        }

        // 使用 Question 的 QuestionnaireId 获取 Questionnaire
        return _dbContext.Questionnaires.FirstOrDefault(q => q.Id == question.QuestionnaireId);
    }
    public List<Response> GetListResponseByQuestionnaireId(int questionnaireId)
    {
        // 通过问卷 ID 查询关联的响应
        return _dbContext.Responses
            .Where(r => r.QuestionnaireId == questionnaireId)
            .ToList();
    }
    // 获取单个 Response
    public Response SelectBy2Id(int userId, int questionnaireId)
    {
        return _dbContext.Responses
            .FirstOrDefault(r => r.UserId == userId && r.QuestionnaireId == questionnaireId);
    }
    // 获取 Response 的数量
    public int GetCountOfResponse(Response response)
    {
        return _dbContext.Responses
            .Count(r => r.UserId == response.UserId && r.QuestionnaireId == response.QuestionnaireId);
    }
    // 根据 ResponseId 获取所有 Answers
    public List<Answer> GetListAnswerByResponseId(int responseId)
    {
        return _dbContext.Answers
            .Where(a => a.ResponseId == responseId)
            .ToList();
    }
    
    public List<Response> SelectAll(Response response)
    {
        // 使用LINQ查询Response列表，按UserId和QuestionnaireId过滤
        return _dbContext.Responses
            .Where(r => r.QuestionnaireId == response.QuestionnaireId && r.UserId == response.UserId)
            .ToList();
    }

    public User SelectUser(Response response)
    {
        // 根据UserId获取User对象
        return _dbContext.Users
            .FirstOrDefault(u => u.Id == response.UserId);
    }
    
    public async Task<Response> GetResponseByIdAsync(int responseId)
    {
        return await _dbContext.Responses.FindAsync(responseId);
    }

    public ResponseDTO ToDTO(Response response)
    {
        if (response == null) return null;

        return new ResponseDTO(
            response.Id,
            response.QuestionnaireId,
            response.UserId,
            response.StartTime,
            response.SubmittedTime,
            response.UpdatedTime,
            response.Answers
        );
    }

    public Response ToEntity(ResponseDTO responseDTO)
    {
        if (responseDTO == null) return null;

        return new Response
        {
            Id = responseDTO.Id,
            QuestionnaireId = responseDTO.QuestionnaireId,
            UserId = responseDTO.UserId,
            StartTime = responseDTO.StartTime,
            SubmittedTime = responseDTO.SubmittedTime,
            UpdatedTime = responseDTO.UpdatedTime,
            Answers = responseDTO.Answers
        };
    }

}